//------------------------------------------------------------------------------
// Copyright (c) 2008 www.dnaide.com
// Licensed under the MIT (MIT-LICENSE.txt)
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.IO;
using System.Resources;

using DNAide.Core;

namespace DNAide.Xml
{

	/// <summary>
	/// Xml helper methods
	/// </summary>
	public partial class XmlAide
	{

		/// <summary>
		/// Returns an xml writer based on a StringAide.StringWriterWithEncoding, default UTF-8
		/// </summary>
		/// <returns></returns>
		public static XmlWriter GetXmlWriterFromStringWriter()
		{
			return GetXmlWriterFromStringWriter(Encoding.UTF8);
		}


		/// <summary>
		/// Returns an xml writer based on a StringAide.StringWriterWithEncoding
		/// </summary>
		/// <param name="encoding"></param>
		/// <returns></returns>
		public static XmlWriter GetXmlWriterFromStringWriter(Encoding encoding)
		{
			XmlWriterSettings settings = new XmlWriterSettings();
			settings.Encoding = encoding;
			return GetXmlWriterFromStringWriter(encoding, settings);
		}


		/// <summary>
		/// Returns an xml writer based on a StringAide.StringWriterWithEncoding
		/// </summary>
		/// <param name="encoding"></param>
		/// <param name="settings"></param>
		/// <returns></returns>
		public static XmlWriter GetXmlWriterFromStringWriter(Encoding encoding, XmlWriterSettings settings)
		{
			StringWriter sWriter = new StringAide.StringWriterWithEncoding(encoding);
			return XmlWriter.Create(sWriter, settings);
		}


		/// <summary>
		/// </summary>
		/// <param name="xmlNode"></param>
		/// <param name="attributeName"></param>
		/// <param name="required"></param>
		/// <param name="returnValue"></param>
		/// <returns></returns>
		internal static XmlNode GetAndRemoveBooleanAttribute(XmlNode xmlNode, String attributeName, Boolean required, ref Boolean returnValue)
		{
			if (xmlNode == null)
			{
				throw new ArgumentNullException("xmlNode");
			}

			XmlNode a = GetAndRemoveAttribute(xmlNode as XmlNode, attributeName, required);
			if (a != null)
			{
				if (a.Value == "true")
				{
					returnValue = true;
				}
				else if (a.Value == "false")
				{
					returnValue = false;
				}
				else
				{
					throw new XmlException(
						StringAide.FormatInvariant(Resources.XmlAide.InvalidBooleanAttribute, a.Name));
				}
			}

			return a;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="xmlNode"></param>
		/// <param name="attributeName"></param>
		/// <param name="required"></param>
		/// <returns></returns>
		internal static XmlNode GetAndRemoveAttribute(XmlNode xmlNode, String attributeName, Boolean required)
		{
			if (xmlNode == null)
			{
				throw new ArgumentNullException("xmlNode");
			}

			XmlNode a = xmlNode.Attributes.RemoveNamedItem(attributeName);

			// If the attribute is required and was not present, throw
			if (required && a == null)
			{
				throw new XmlException(
					StringAide.FormatInvariant(Resources.XmlAide.MissingRequiredAttribute, attributeName, xmlNode.Name));
			}

			return a;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="xmlNode"></param>
		/// <param name="attributeName"></param>
		/// <param name="required"></param>
		/// <param name="returnValue"></param>
		/// <returns></returns>
		internal static XmlNode GetAndRemoveNonEmptyStringAttribute(XmlNode xmlNode, String attributeName, Boolean required, ref String returnValue)
		{
			XmlNode a = GetAndRemoveStringAttribute(xmlNode, attributeName, required, ref returnValue);
			if (a != null && returnValue.Length == 0)
			{
				throw new XmlException(
					StringAide.FormatInvariant(Resources.XmlAide.EmptyAttribute, attributeName));
			}

			return a;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="xmlNode"></param>
		/// <param name="attributeName"></param>
		/// <param name="required"></param>
		/// <param name="returnValue"></param>
		/// <returns></returns>
		internal static XmlNode GetAndRemoveStringAttribute(XmlNode xmlNode, String attributeName, Boolean required, ref String returnValue)
		{
			XmlNode a = GetAndRemoveAttribute(xmlNode, attributeName, required);
			if (a != null)
			{
				returnValue = a.Value;
			}

			return a;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="xmlNode"></param>
		internal static void CheckForUnrecognizedAttributes(XmlNode xmlNode)
		{
			if (xmlNode == null)
			{
				throw new ArgumentNullException("xmlNode");
			}

			if (xmlNode.Attributes.Count != 0)
			{
				throw new XmlException(
					StringAide.FormatInvariant(Resources.XmlAide.ConfigBaseUnrecognizedAttribute, xmlNode.Attributes[0].Name));
			}
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="xmlNode"></param>
		internal static void CheckForNonCommentChildNodes(XmlNode xmlNode)
		{
			if (xmlNode == null)
			{
				throw new ArgumentNullException("xmlNode");
			}

			foreach (XmlNode childNode in xmlNode.ChildNodes)
			{
				if (childNode.NodeType != XmlNodeType.Comment)
				{
					throw new XmlException(
						StringAide.FormatInvariant(Resources.XmlAide.ConfigBaseNoChildNodes));
				}
			}
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="xmlNode"></param>
		/// <param name="attributeName"></param>
		internal static void CheckForbiddenAttribute(XmlNode xmlNode, String attributeName)
		{
			if (xmlNode == null)
			{
				throw new ArgumentNullException("xmlNode");
			}

			XmlAttribute attr = xmlNode.Attributes[attributeName];
			if (attr != null)
			{
				throw new XmlException(
					StringAide.FormatInvariant(Resources.XmlAide.ConfigBaseUnrecognizedAttribute, attributeName));
			}
		}


	}
}
